package process

import (
	"encoding/binary"
	"encoding/json"
	"fmt"
	"go_code/chatroom/client/utils"
	"go_code/chatroom/common/message"
	"net"
	"os"
)

type UserProcess struct {

}

//用户注册
func (this *UserProcess) Register(userId int, userPwd string, userName string) (err error) {
	//连接服务器
	conn, err := net.Dial("tcp", "localhost:8889")
	if err != nil {
		fmt.Println("net.Dial err", err)
		return
	}

	//延时关闭
	defer conn.Close()

	//准备通过conn发送消息到服务器
	var mes message.Message
	mes.Type = message.RegisterMesType
	//创建一个loginMes 结构体
	var registerMes message.RegisterMes
	registerMes.User.UserId = userId
	registerMes.User.UserPwd = userPwd
	registerMes.User.UserName = userName

	//将RegisterMes序列化
	data, err := json.Marshal(registerMes)
	if err != nil {
		fmt.Println("json.Marshal err=", err)
		return
	}

	//把data赋给 mes.Data字段
	mes.Data = string(data)

	//将mes进行序列化
	data, err = json.Marshal(mes)
	if err != nil {
		fmt.Println("json.Marshal err=", err)
	}

	tf := &utils.Transfer{
		Conn: conn,
	}

	//发送给服务端
	err = tf.WritePkg(data)
	if err != nil {
		fmt.Println("60 注册发送信息错误", err)
		return
	}

	mes, err = tf.ReadPkg()	//mes就是  registerMes
	if err != nil {
		fmt.Println("readPkg(conn) err", err)
		return
	}


	//将mes的Data部分反序列化成LoginResMes
	var registerResMes message.RegisterResMes
	err = json.Unmarshal([]byte(mes.Data), &registerResMes)
	if err != nil {
		fmt.Println("json.Unmarshal fail=", err)
	}
	if registerResMes.Code == 200 {
		fmt.Println("注册成功，可以重新登陆！")
	}else {
		fmt.Println("81 registerResMes=err", registerResMes.Error)
	}

	os.Exit(0)
	return
}

//写一个函数，完成登陆
func (this *UserProcess) Login(userId int, passWord string) (err error){
	//开始定协议

	//连接服务器
	conn, err := net.Dial("tcp", "localhost:8889")
	if err != nil {
		fmt.Println("net.Dial err", err)
		return
	}

	//延时关闭
	defer conn.Close()

	//准备通过conn发送消息到服务器
	var mes message.Message
	mes.Type = message.LoginMesType
	//创建一个loginMes 结构体
	var loginMes message.LoginMes
	loginMes.UserId = userId
	loginMes.UserPwd = passWord

	//将loginMes序列化
	data, err := json.Marshal(loginMes)
	if err != nil {
		fmt.Println("json.Marshal err=", err)
		return
	}
	//把data赋给 mes.Data字段
	mes.Data = string(data)

	//将mes进行序列化
	data, err = json.Marshal(mes)
	if err != nil {
		fmt.Println("json.Marshal err=", err)
	}

	//data就是我们要发送到数据
	//把data到长度发送给服务器，data到长度 ->转成一个表示长度到切片
	var pkgLen uint32		//约等于4G数据
	pkgLen = uint32(len(data))
	var buf [4]byte
	binary.BigEndian.PutUint32(buf[0:4], pkgLen)

	//发送长度
	n, err := conn.Write(buf[:4])
	if n != 4 || err != nil {
		fmt.Println("conn.Write(byte) err=",err)
		return
	}

	fmt.Println("客户端发送消息长度成功。。。", len(data), string(data))
	//发送消息本身
	_, err = conn.Write(data)
	if err != nil {
		fmt.Println("conn.Write(data) err=",err)
		return
	}

	//休眠20s，本身发完登陆消息会话就会关闭，加了延迟后好进行查看效果
	//time.Sleep(10 * time.Second)
	//fmt.Println("休眠20s")

	tf := &utils.Transfer{
		Conn: conn,
	}
	mes, err = tf.ReadPkg()	//mes就是
	if err != nil {
		fmt.Println("readPkg(conn) err", err)
		return
	}

	//将mes的Data部分反序列化成LoginResMes
	var loginResMes message.LoginResMes
	err = json.Unmarshal([]byte(mes.Data), &loginResMes)
	if err != nil {
		fmt.Println("json.Unmarshal fail=", err)
		return
	}
	if loginResMes.Code == 200 {
		//初始化CurUser
		CurUser.Conn = conn
		CurUser.UserId = userId
		CurUser.UserStatus = message.UserBusyStatus

		//fmt.Println("登陆成功！")
		//显示当前在线用户到列表
		fmt.Println("当前用户在线列表如下：")
		for _, v := range loginResMes.UsersId{			//process.userProcess 172行那里维护了一个全局的userId列表，登陆成功后会返回所有在线用户id
			if v ==  userId{
				continue
			}
			fmt.Println("用户id:", v)
			//完成客户端到初始化
			user := &message.User{
				UserId: v,
				UserStatus: message.UserOnline,
			}
			onlineUsers[v] = user
		}
		fmt.Println("==============================")

		//启动一个协程，保持和服务器端端通讯，如果有数据推送给客户端
		go serverProcessMes(conn)

		//1、循环显示菜单
		for true {
			ShowMenu()
		}
	}else {
		fmt.Println("102 loginResMes.Code == 500", loginResMes.Error)
	}

	return
}

//关联一个用户登陆到方法




